/**
 * 继承多态+抽象类接口
 */
//想要实现多态，需要满足几个条件
// 1.继承关系上->向上转型
// 2.子类和父类 有同名的 覆盖/重写 方法
// 3.通过父类对象的引用 去调用这个重写的方法
// 完成以上3部分，就会发生动态绑定，而动态绑定是多态的基础
class Animal{
    public  String name;
    public  int age;
    public Animal(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void eat(){
        System.out.println(this.name+"正在吃饭！");
    }
}
class Dog extends Animal{
    public Dog(String name,int age){
        //帮助初始化了子类从父类继承下来的成员变量
        super(name,age);
    }
    public void bark(){
        System.out.println(this.name+"汪汪叫！");
    }
    @Override
    public void eat(){
        System.out.println(this.name+" 正在吃狗粮！");
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
class Cat extends Animal{
    public Cat(String name,int age){
        super(name,age);
    }
    public void miaomiao(){
        System.out.println(this.name+"咪咪叫！");
    }

    @Override
    public void eat() {
        System.out.println(this.name+" 正在吃猫粮！");
    }
}




public class nine {
    //向下转型 本身不安全
    public static void main(String[] args) {
        Animal animal = new Dog("圆圆",19);
       // animal.back;
       /* Dog dog =(Dog)animal;
        dog.bark();*/

        //如果animal引用的对象 是Cat对象 的实例
        if(animal instanceof Cat){
            Cat cat =(Cat) animal;
            cat.miaomiao();
        }else{
            System.out.println("哈哈，我理解了！！！");
        }
    }

    public static void eatFun(Animal animal){
        animal.eat();
    }
    public static void main6(String[] args) {
        Dog dog = new Dog("圆圆",19);
        eatFun(dog);
        Cat cat = new Cat("十三月",1);
        eatFun(cat);
    }

    public static void main5(String[] args) {
        Animal animal = new Dog("圆圆",19);
        animal.eat();
        Animal animal1 = new Cat("十三月",1);
        animal1.eat();
    }



    public static void main4(String[] args) {
        /*Animal animal = new Dog("圆圆",19);
        animal.eat();*/

        Dog dog = new Dog("圆圆",19);
        System.out.println(dog);
    }

    //向上转型  常见的 可以发生 向上转型的三个机制
    // 1.直接赋值
    // 2.方法的参数，传参的时候，进行向上转型
    // 3.返回值 向上转型
    public static void func1(Animal animal){

    }
    public static Animal func2(){
        Dog dog = new Dog("圆圆",19);
        return dog;
    }
    public static void main3(String[] args) {
        Dog dog = new Dog("圆圆",19);
        func1(dog);

        Animal animal = func2();
    }



    public static void main2(String[] args) {
        /*Dog dog = new Dog("圆圆",19);
        Animal animal = dog;*/

        Animal animal = new Dog("圆圆",19);
        animal.eat();//父类自己的eat

    }
    public static void main1(String[] args) {
        Dog dog = new Dog("圆圆",19);
        dog.eat();
        dog.bark();
        System.out.println("=========");
        /*Animal animal = new Animal("fafa",18);
        animal.eat();
        animal.bark;
        结论：通过父类的引用 只能调用父类自己特有的成员 方法/成员变量
        */
    }
}
